package cn.cmcc.online.smsapi.sdk.service.baseparse;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

import org.json.JSONArray;
import org.json.JSONObject;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Process;
import cn.cmcc.online.smsapi.sdk.Iservice.XyCallBack;
import cn.cmcc.online.smsapi.sdk.constant.Constant;
import cn.cmcc.online.smsapi.sdk.db.entity.SysParamEntityManager;
import cn.cmcc.online.smsapi.sdk.dex.DexUtil;
import cn.cmcc.online.smsapi.sdk.iccid.IccidLocationUtil;
import cn.cmcc.online.smsapi.sdk.log.LogManager;
import cn.cmcc.online.smsapi.sdk.queue.SdkTaskQueue;
import cn.cmcc.online.smsapi.sdk.queue.TaskInfo;
import cn.cmcc.online.smsapi.sdk.threadpool.SmartSmsThreadPoolManager;
import cn.cmcc.online.smsapi.sdk.util.ConversationManager;
import cn.cmcc.online.smsapi.sdk.util.DuoquUtils;
import cn.cmcc.online.smsapi.sdk.util.JarSubCheckQueue;
import cn.cmcc.online.smsapi.sdk.util.StringUtils;
import cn.cmcc.online.smsapi.util.ParseBubbleManager;
import cn.cmcc.online.smsapi.util.ParseManager;
import cn.cmcc.online.smsapi.util.UUIDUtils;
/*SDK-633 hewengao 20161009 end*/
/**
 * 基础识别解析服务
 * @author hewengao
 *
 */
public class BaseParseService{
    static long addTaskTime = 0L;
    static String provice = null;
    /* SDK-754 songzhirong 20170407 start */
    static String areaCode = null;
    /* SDK-754 songzhirong 20170407 end */
    static BaseParseCallable baseParseCallable =new BaseParseCallable();
    static boolean isMainValided = false;
    /**
	 * 基础识别解析入口
	 * @param ctx
	 * @param phoneNumber
	 * @param smsCenterNum
	 * @param smsContent
	 * @param smsTime
	 * @param extend
	 * @return
	 * @throws Exception
	 */
     static Map<String, Object> baseParseMsg(Context ctx, String phoneNumber, String smsCenterNum, String smsContent, long smsTime, Map<String, String> extend) throws Exception {

    	 if (ctx == null) {
             throw new Exception(" Context is null.");
         }

         if (phoneNumber == null) {
             throw new Exception(" phoneNumber is null.");
         }
         if (smsContent == null) {
             throw new Exception(" smsContent is null.");
         }
         /*SDK-431 songzhirong 20160530 start*/
         Map<String, Object> res = null;
         String uuid = UUIDUtils.uniqId();
         try { 
          ConversationManager.saveLogIn(uuid,"cn.com.xy.sms.sdk.service.baseparse.BaseParseService", "parseMsg",  ctx,  phoneNumber,  smsCenterNum,  smsContent,  smsTime,  extend);
          /*SDK-431 songzhirong 20160530 end*/
          String strSmsTime = String.valueOf(smsTime);
         /* SDK-402 huangzhiqiang 20160420 start */
         if (extend == null) {
             extend = new HashMap<String, String>();
         }
         /*huangzhiqiang 20160927 start*/
//         else {
 //            if (extend.containsKey("msgId")) {
 //                String msgId = extend.get("msgId");
 //                /* SDK-591 huangzhiqiang 20160815 start */
 //                // remove old cache
 //                ParseRichBubbleManager.deleteParseDataFromCache(msgId);
//                 /* SDK-591 huangzhiqiang 20160815 end */
 //            }
//         }
         /*huangzhiqiang 20160927 end*/
         /* SDK-402 huangzhiqiang 20160420 end */

         // 假如扩展参数中，没有设置兜底验证码，就默认为true
         if (!extend.containsKey(Constant.KEY_ALLOW_VERCODE_MSG)) {
             extend.put(Constant.KEY_ALLOW_VERCODE_MSG, "true");
         }

         // 私人转发，需要增加实现是否为联系人接口
         if (extend.containsKey(Constant.KEY_ALLOW_PERSONAL_MSG)) {
             boolean isContact = DuoquUtils.getSdkDoAction().isContact(ctx, phoneNumber);
             if (!isContact) {
                 extend.put(Constant.KEY_ALLOW_PERSONAL_MSG, "false");
             }
         }
         // long st = System.currentTimeMillis();
         extend.put("version", DexUtil.getSceneVersion());
         extend.put("channel", SysParamEntityManager.getStringParam(ctx, Constant.CHANNEL));
         extend.put("smsCenterNum", smsCenterNum);
         // long ed = System.currentTimeMillis();
         // LogManager.d("duoqu_test", "parseMsg getStringParam: "+(ed -st));
         if (provice == null) {
             provice = IccidLocationUtil.getProvince();
         }
         // ed = System.currentTimeMillis();
         // LogManager.d("duoqu_test", "parseMsg getProvince: "+(ed -st));
         /* SDK-754 songzhirong 20170407 start */
         if (!StringUtils.isNull(provice)) {
             extend.put("provice", provice);
         }        
         if(areaCode == null){
        	 areaCode = IccidLocationUtil.getAreaCoce();
         }
         if (!StringUtils.isNull(areaCode)) {
             extend.put("areaCode", areaCode);
         }
         /* SDK-754 songzhirong 20170407 end */
         int level = SysParamEntityManager.getIntParam(Constant.getContext(), Constant.RECOGNIZE_LEVEL);
         if (level != -1) {
             extend.put(Constant.RECOGNIZE_LEVEL, level + "");
         }
         // ed = System.currentTimeMillis();
         // LogManager.d("duoqu_test", "parseMsg getIntParam: "+(ed -st));
         
         JSONArray timeSubInfo = DuoquUtils.getSdkDoAction().getTimeSubInfo(smsContent, smsTime);
         extend.put(Constant.KEY_HW_PARSE_TIME, timeSubInfo == null ? "" : timeSubInfo.toString());

         /*SAMSUNGCS-534 zhaojiangwei 20160930 start*/
         String rawSmsContent = new String(smsContent);
         /*SAMSUNGCS-534 zhaojiangwei 20160930 start*/
         
         smsContent = smsContent.trim();
         boolean isNewSms = "1".equals(extend.get("from"));
             /*SDK-690 hewengao 20161130 start*/
         if (isMainValided || ParseManager.parseUtilMainJarIsReady()) {
             isMainValided = true;
             /*SDK-690 hewengao 20161130 end*/
             // LogManager.d("parseMsg", " online is ok.");
             if ("true".equals(extend.get("parseVerifyCode"))) {
                 res = DexUtil.parseVerifyCodeToMap(phoneNumber, smsContent, extend);
             } else {
                 res = DexUtil.parseMsgToMap(phoneNumber, smsContent, extend);
             }
             /*SDK-622 hewengao 20161101 start*/
             if (res == null) {
                 //LogManager.e("parseMsg", "result is null phoneNumber:" + phoneNumber + " smsContent: " + smsContent + " msgID: " + extend.get("msgId"), null);
                 /* SDK-421 huangzhiqiang 20160525 start */
                 // 不能识别的短信进行分片上报处理
                 SdkTaskQueue.addTask(new TaskInfo(16, "num", phoneNumber, "msg", smsContent, "smsTime", strSmsTime));
                 /* SDK-421 huangzhiqiang 20160525 end */
                 
                 /*MEIZU-2258 zhaojiangwei 20170313 start */
                 /*SDK-674 hewengao 20161114 start*/
                 //DuoquUtils.getSdkDoAction().logInfo(Constant.TAG,"baseParseMsg is null.",null);
                 /*SDK-674 hewengao 20161114 end*/
                 /*MEIZU-2258 zhaojiangwei 20170313 end */
             }
             //对新接收的短信进行分析和统计
             if(isNewSms) {
             //  号码对应短信识别次数上报接口
                 TaskInfo taskInfo = new TaskInfo(14, "phoneNumber", phoneNumber, "isSuccess", String.valueOf(res != null));
                 SdkTaskQueue.addTask(taskInfo);
             }
             /*SDK-622 hewengao 20161101 end*/
             // LogManager.d("parseMsg", " online is ok.");
         } else {
             /*SDK-674 hewengao 20161114 start*/
             DuoquUtils.getSdkDoAction().logInfo(Constant.TAG,"parseUtilMain not valid.",null);
             /*SDK-674 hewengao 20161114 end*/
        	 /*SDK-463 hewengao 20160627 start*/
        	 JarSubCheckQueue.runJarSubCheckQueue();
        	 /*SDK-463 hewengao 20160627 end*/
             // LogManager.d("parseMsg", " online is not ok. use local.");
             // res= ParseUtilCommon.parseMessage(phoneNumber, smsContent,
             // extend);

         }
         /*SDK-712 zhaojiangwei 20161228 start*/
         boolean isInitData = ParseManager.isInitData();
         /*SDK-712 zhaojiangwei 20161228 end*/
         if (isInitData == false) {
             // 未初始化完毕,放在最后的目的，是由于本地没有内嵌数据时，需要走识别流程，才能去获取所属的数据。否则永远拿不到数据。无法识别。
             res = new HashMap<String, Object>();
             res.put("parseStatu", -1);
             DuoquUtils.getSdkDoAction().logInfo(Constant.TAG,"parse msg parseStatu = -1",null);
             return res;
         }
         // ed = System.currentTimeMillis();
         // LogManager.d("duoqu_test", "parseMsg parseMsgToMap: "+(ed -st));

         /*SDK-446 /songzhirong/2016.05.20---start---*/
         // 十分钟之后再次调用
         if (System.currentTimeMillis() >= (addTaskTime + Constant.addTaskForTime)) {
             SdkTaskQueue.addTask(new TaskInfo(2));
             addTaskTime = System.currentTimeMillis();
         }
         /*SDK-446 /songzhirong/2016.05.20---end---*/

         /*SDK-662 jinzhengbin&songzhirong 20161104 start*/
         /*SDK-622 hewengao 20161101 start*/
         if(res == null || !res.containsKey("from_cache")) {
                /* RM-1351 huangzhiqiang 20170407 start */
                SdkTaskQueue.addTask(new TaskInfo(9, "num", phoneNumber, "msg", smsContent, "cnum", smsCenterNum,
                        "smsTime", strSmsTime, "isNewSms", String.valueOf(isNewSms)));
                /* RM-1351 huangzhiqiang 20170407 end */
                if (isNewSms) {
                    SdkTaskQueue.addTask(new TaskInfo(10, "num", phoneNumber, "msg", smsContent, "cnum", smsCenterNum,
                            "smsTime", strSmsTime));
                }  
         }
         /*SDK-622 hewengao 20161101 end*/
         /*SDK-662 jinzhengbin&songzhirong 20161104 end*/
         
         if (res != null) {
             String simIndex = extend.get("simIndex");
             if (!StringUtils.isNull(simIndex)) {
                 res.put("simIndex", simIndex);
             }
             String msgTime = extend.get("msgTime");
             if (!StringUtils.isNull(msgTime)) {
                 res.put("msgTime", extend.get("msgTime"));
             }
             /*ONEPLUS-1302 / wangxingjian 2016 0830 -- begin*/
             else if(smsTime >= 0L){
                res.put("msgTime", String.valueOf(smsTime));
             }
             /*ONEPLUS-1302 / wangxingjian 2016 0830 -- end*/
             String titleNum = (String) res.get("title_num");
             /*SDK-622 hewengao 20161101 start*/
             if (!StringUtils.isNull(titleNum) && !res.containsKey("from_cache")) {
             /*SDK-622 hewengao 20161101 end*/
                 String iccid = extend.get("simIccid");
                 // 加入队列
                 if (!StringUtils.isNull(iccid)) {
                     SdkTaskQueue.addTask(new TaskInfo(1, "simIccid", iccid, "receiveNum", phoneNumber, "sms", smsContent, "centerNum", smsCenterNum, "sceneId", titleNum));
                 }
                 // 统计解析情景号次数
                 SdkTaskQueue.addTask(new TaskInfo(6, "titleNo", titleNum));

                 // 解析成功，统计打点
                 SdkTaskQueue.addTask(new TaskInfo(3, "titleNo", titleNum));

                 SdkTaskQueue.addTask(new TaskInfo(8, "titleNo", titleNum));
                 // 收集类型点击类型，识别默认为“0”
                 SdkTaskQueue.addTask(new TaskInfo(5, "titleNo", titleNum, "type", "0"));
                 /*SDK-678 hewengao 20161115 start*/
                 HashMap<String, Object> parseResult = new HashMap<String, Object>();
                 parseResult.putAll(res);
                  /*SDK-678 hewengao 20161115 end*/
             }
            
         }

         /* SDK-383 解析特征值  xusongzhou 20160412 start */
         if(Boolean.valueOf(extend.get("parse_recognise_value"))) {
             String msgId = extend.get("msgId");
             if(!StringUtils.isNull(msgId)) {
            	 /*SDK-458 hewengao 20160525 start */
            	 TaskInfo taskInfo= new TaskInfo(15, "msgId", msgId, "num", phoneNumber, "cnum", smsCenterNum,
                         "msg", rawSmsContent, "smsTime", strSmsTime);
            	 try{
	            	 if(res !=null && !StringUtils.isNull(extend.get("ref_basevalue")) && Boolean.valueOf(extend.get("ref_basevalue"))){
	            		 //特征值识别依懒基础识别
	            		 res.remove("ref_basevalue");
	            		 Map baseValue = new HashMap();
	            		 baseValue.putAll(res);
	            		 taskInfo.setExtend(baseValue);
	            	 }
            	 }catch(Exception e){}
            	 SdkTaskQueue.addTask(taskInfo);
            	 /*SDK-458 hewengao 20160525 end */
             }
         }
         /* SDK-383 解析特征值  xusongzhou 20160412 end */
         /*SDK-382 /songzhirong/2016.05.17---start---*/
         DexUtil.handleParseMsg(ctx,  extend.get("msgId"),phoneNumber, smsCenterNum, smsContent, smsTime, extend, res);
         /*SDK-382 /songzhirong/2016.05.17---end---*/
         /*SDK-431 songzhirong 20160530 start*/
         } catch (Throwable e) {
             LogManager.e(Constant.TAG, "BaseParseService parseMsg: ", e);
             /* SDK-584 zhaojiangwei 20160906 start */
             DexUtil.saveExceptionLog(e);
             /* SDK-584 zhaojiangwei 20160906 end */
         }finally{
            ConversationManager.saveLogOut(uuid,"cn.com.xy.sms.sdk.service.baseparse.BaseParseService", "parseMsg",  ctx,  phoneNumber,  smsCenterNum,  smsContent,  smsTime,  extend,res);
         }       
         /*SDK-431 songzhirong 20160530 end*/
        return res;
     }
     /* SDK-454 hewengao/20160523 end */
	/**
	 * 基础识别解析入口
	 * @param ctx
	 * @param phoneNumber
	 * @param smsCenterNum
	 * @param smsContent
	 * @param smsTime
	 * @param extend
	 * @return
	 * @throws Exception
	 */
	public synchronized static Map<String, Object> parseMsg(final Context ctx,final String phoneNumber, final String smsCenterNum,final String smsContent,final long smsTime, final Map<String, String> extend) throws Exception {
		/* SDK-454 hewengao/20160523 start */
		Map<String, Object> res = null;
		Future<Map<String, Object>> feature = null;
		try {
			baseParseCallable.setParam(ctx, phoneNumber, smsCenterNum, smsContent, smsTime, extend);
            /* SDK-616 hewengao 20160912 start */
            feature = SmartSmsThreadPoolManager.baseParseService.submit(baseParseCallable);
            /* SDK-616 hewengao 20160912 end */
			long parseTimeOut = 0;
			try{
				if(extend != null && extend.containsKey("PARSE_TIME_OUT")){
					parseTimeOut = Long.valueOf(extend.get("PARSE_TIME_OUT"));
				}
			}catch(Exception e){
				LogManager.e("XIAOYUAN", "parseMsg PARSE_TIME_OUT", e);
			}
            /*SDK-707 hewengao/20161226 start*/
			if(parseTimeOut == 0){
				parseTimeOut = 6000;
			}
            /*SDK-707 hewengao/20161226 end*/
			if (feature!=null) {
				res = feature.get(parseTimeOut, TimeUnit.MILLISECONDS);
			}
		} catch (Throwable e) {
			/*SDK-474 hewengao 20160603 start*/
			LogManager.e(Constant.TAG, "BaseParseService_parseMsg", e);
			/*SDK-474 hewengao 20160603 end*/
			
			/* SDK-542 huangzhiqiang 20160718 start */
            if (e instanceof TimeoutException || e instanceof InterruptedException) {
                try {
                    DuoquUtils.getSdkDoAction().logInfo(Constant.TAG," baseparse timeout or interrupted",null);
                    if (feature != null) {
                        feature.cancel(true);
                    }
                } catch (Throwable ex) {
                }
                try {
                    baseParseCallable.stopThread();
                    /* SDK-616 hewengao 20160912 start */
                    SmartSmsThreadPoolManager.baseParseService.shutdownNow();
                    /* SDK-616 hewengao 20160912 start */
                } catch (Throwable ex) {
                }
                SmartSmsThreadPoolManager.baseParseService = Executors.newFixedThreadPool(1);
                res = new HashMap<String, Object>();
                res.put("parseStatu", -1);
            }
			/* SDK-542 huangzhiqiang 20160718 end */
		}finally{
			baseParseCallable.destory();
		}
		/* SDK-454 hewengao/20160523 end */
		return res;
    }
	
	/* SDK-514 zhaojiangwei 20160630 start */
	public static void parseMsgAsyn(final Context ctx, final String msgId, final String phoneNumber,
			final String smsCenterNum, final String smsContent, final long smsTime, final Map<String, String> extend,
			final XyCallBack parseCallBack) {
		if(parseCallBack == null){
			return;
		}
        /* SDK-616 hewengao 20160912 start */
//        SmartSmsThreadPoolManager.baseParseServiceAsyn;
        SmartSmsThreadPoolManager.getBaseParseServiceAsyn().execute(new Runnable() {
        /* SDK-616 hewengao 20160912 end */
			@Override
			public void run() {
				try {
                    /*SDK-633 hewengao 20161009 start*/
                    SmartSmsThreadPoolManager.setThreadNameAndPriority(SmartSmsThreadPoolManager.TNAME_FEATUREPASE, Process.THREAD_PRIORITY_BACKGROUND);
                    /*SDK-633 hewengao 20161009 end*/
                    Map<String, Object> map = parseMsg(ctx, phoneNumber, smsCenterNum, smsContent, smsTime, extend);
					if (map != null  ) {
						parseCallBack.execute(map);
					}
				}
				catch (Throwable e) {
					LogManager.e(Constant.TAG, "ParseSmsMessage parseMsgAsyn error:", e);
				}
			}
		});
	}
	/* SDK-514 zhaojiangwei 20160630 end */
	
	private static BroadcastReceiver mBroadcastReceiver = null;
	/* SDK-657 zhaojiangwei 20161101 start */
	public synchronized static void registerReceiver(Context context,final Map<String, String> extend) {
	/* SDK-657 zhaojiangwei 20161101 end */
        try {
            boolean register = true;
   		    try {
   	            if (extend != null
   	                    && Boolean.FALSE.toString().equalsIgnoreCase((String) extend.get(Constant.REGISTOR_ICCID_RECIVER))) {
   	            	register = false;
   	            	LogManager.d("xiaoyuan", "不注册mBroadcastReceiver广播");
   	            }
   	        } catch (Throwable e) {
   	            LogManager.e(Constant.TAG, "init SDK ", e);
   	        }
            if (mBroadcastReceiver == null && register) {
                mBroadcastReceiver = new BroadcastReceiver() {

                    @Override
                    public void onReceive(Context context, Intent intent) {
                        String action = intent.getAction();
                        if (ParseManager.UPDATE_ICCID_INFO_CACHE_ACTION.equals(action)) {
                            /* SDK-485 huangzhiqiang 20160622 start */
                            updateIccidCache(intent);
                            /* SDK-485 huangzhiqiang 20160622 end */
                        }
                    }
                };
                IntentFilter filter = new IntentFilter();
                filter.addAction(ParseManager.UPDATE_ICCID_INFO_CACHE_ACTION);
                context.registerReceiver(mBroadcastReceiver, filter);
            }
        } catch (Throwable e) {
            LogManager.e("initSdk", "registerReceiver error ", e);
        }
    }

    /* SDK-485 huangzhiqiang 20160622 start */
    private static void updateIccidCache(Intent intent) {
        if (intent == null) {
            return;
        }
        String iccid = intent.getStringExtra("iccid");
        int simIndex = intent.getIntExtra("simIndex", -1);
        IccidLocationUtil.updateIccidCache(iccid, simIndex);
    }
    /* SDK-485 huangzhiqiang 20160622 end */

    // 注销广播接收者
    /* SDK-657 zhaojiangwei 20161101 start */
    public synchronized static void unRegisterReceiver(Context context) {
    /* SDK-657 zhaojiangwei 20161101 end */
        try {
            if (mBroadcastReceiver != null) {
                context.unregisterReceiver(mBroadcastReceiver);
                mBroadcastReceiver = null;
            }
        } catch (Throwable e) {
            LogManager.e("ParseManager.unRegisterReceiver", "unRegisterReceiver error ", e);
        }
    }

    
    public static String getAdAction( Map<String, Object> valueMap,Map<String, String> extend){
    	try {
        	if(valueMap==null||valueMap.isEmpty()) return "";
        	
        	String isUseNewAction = null;
        	Object newAction = "";
            if(extend != null) {
            	isUseNewAction = extend.get("isUseNewAction");
            }
            newAction = valueMap.get("NEW_ADACTION");
            if("true".equalsIgnoreCase(isUseNewAction)&&null!=newAction && 
            		!StringUtils.isNull(newAction.toString())){
            	return (String) newAction;            	
            }else{
            	return (String) valueMap.get("ADACTION");
            }
           
		} catch (Throwable e) {
			// TODO: handle exception
		}
    	return "";
    }
    /*MEIZU-2295 songzhirong 20170330 start*/
    public static Map<String, Object>  parseMessage(Context ctx, String phoneNumber,String smsContent,String smsCenterNum,long smsTime,Map<String, String> extend) throws Exception{
    	try {
    		Map<String, Object> res = parseMsg(ctx, phoneNumber, smsCenterNum, smsContent, smsTime, extend);     	     
            if (res != null && ParseBubbleManager.getParseStatu(res) != -1) {     
                Map<String, Object> handresult = DexUtil.handerBubbleValueMap(res);
                return handresult;
            } 
		} catch (Exception e) {
			// TODO: handle exception
		}
    	return null;
    	
    }
    /*MEIZU-2295 songzhirong 20170330 end*/
}
